package com.gitee.hermer.engine.jars.dependent.activemq.core;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.gitee.hermer.boot.jee.commons.log.UtilsContext;
import com.gitee.hermer.boot.jee.commons.number.IntegerUtils;
import com.gitee.hermer.boot.jee.commons.utils.StringUtils;
import com.gitee.hermer.engine.jars.core.domain.EngineConstant;
import com.gitee.hermer.engine.jars.dependent.activemq.config.ActiveMQProperties;
import com.gitee.hermer.engine.jars.dependent.activemq.core.pool.ActiveMQSessionPoolFactory;



public class ActiveMQContext extends UtilsContext implements DisposableBean,Runnable,InitializingBean{

	private String[] brokers;
	private int monitorIntervalTime;
	private boolean isUseAsyncSend = false;
	private boolean isUseTransacted = true;
	private int createSessionOutTime = 2000;
	private int maxIdle = 100;
	private int maxTotal = 100;
	private int minIdle = 100;

	private AtomicBoolean isInited = new AtomicBoolean(false);


	public ActiveMQContext(String[] brokerURLs){
		this(brokerURLs,0,false,false,0,0,0,0);
	}

	public ActiveMQContext(ActiveMQProperties properties){
		this(properties.getBrokers(), properties.getMonitorIntervalTime(), 
				properties.getIsUseAsyncSend(), properties.getIsUseTransacted(), 
				properties.getCreateSessionOutTime(), properties.getMaxIdle(), properties.getMaxTotal(), properties.getMinIdle());
	}

	public ActiveMQContext(String[] brokerURLs, int monitorIntervalTime, boolean isUseAsyncSend,boolean isUseTransacted, int createSessionOutTime, int maxIdle, int maxTotal,
			int minIdle) {
		super();
		this.brokers = brokerURLs;
		this.monitorIntervalTime =IntegerUtils.defaultIfZero(monitorIntervalTime, 1000);
		this.isUseAsyncSend = isUseAsyncSend;
		this.isUseTransacted = isUseTransacted;
		this.createSessionOutTime = IntegerUtils.defaultIfZero(createSessionOutTime, 2000);
		this.maxIdle = IntegerUtils.defaultIfZero(maxIdle, 100);
		this.maxTotal = IntegerUtils.defaultIfZero(maxTotal, 100);
		this.minIdle = IntegerUtils.defaultIfZero(minIdle, 100);
		info("读取配置 -> brokerURLs[%s],monitorIntervalTime[%s],isUseAsyncSend[%s],isUseTransacted[%s],createSessionOutTime[%s],maxIdle[%s],maxTotal[%s],minIdle[%s]",
				this.brokers,this.monitorIntervalTime,this.isUseAsyncSend,this.isUseTransacted,this.createSessionOutTime,this.maxIdle,this.maxTotal,this.minIdle);
	}

	@Autowired
	private ActiveMQManager manager;


	public int getCreateSessionOutTime()
	{
		return this.createSessionOutTime;
	}

	public boolean isUseAsyncSend()
	{
		return this.isUseAsyncSend;
	}

	public int getMaxIdle()
	{
		return this.maxIdle;
	}

	public int getMaxTotal()
	{
		return this.maxTotal;
	}

	public int getMinIdle()
	{
		return this.minIdle;
	}

	public String[] getBrokerURL() {
		return brokers;
	}
	public boolean isUseTransacted() {
		return isUseTransacted;
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		if(isInited.compareAndSet(false, true)){
			new Thread(this).start();
		}
	}


	@Override
	public void destroy() throws Exception {
		info("ActiveMQContext Destroy...");
		if (this.manager != null) {
			this.manager.destroy();
		}
	}

	public void monitor()
	{
		if(this.manager != null)
			this.manager.monitor();
	}

	@Override
	public void run() {
		for (;;)
		{
			try
			{
				monitor();
				Thread.sleep(this.monitorIntervalTime);
			}
			catch (Exception e)
			{
				error("mq monitor error,", e);
				try
				{
					Thread.sleep(2000L);
				}
				catch (InterruptedException localInterruptedException) {}
			}
		}
	}

	public ActiveMQSessionPoolFactory getFactory(String terminalId)
	{
		return this.manager.getMQSessionFacory(terminalId);
	}

	public List<ActiveMQSessionPoolFactory> getAllFactory()
	{
		return this.manager.getFactory();
	}

}
